package edu.tms.excel;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;

public class BuildHSSF<T> {
	/**
	 * Excel工作薄
	 */
	private HSSFWorkbook wb;
	/**
	 * 当前Excel工作表
	 */
	private HSSFSheet sheet;
	/**
	 * 样式对象
	 */
	private HSSFCellStyle style;
	/**
	 * 下一行
	 */
	private int nextRow;
	private int curRow;
	private int previousRow;
	/**
	 * 当前行的当前列
	 */
	private int curCol;
	private int previousCol;
	private int nextCol;
	private HSSFRow row;
	private HSSFCell curCell;

	
	public BuildHSSF(String sheetName){
		wb = new HSSFWorkbook();
		sheet = wb.createSheet(sheetName);
		style = wb.createCellStyle();
		nextRow = previousRow = curRow = 0;
		nextCol = previousCol = curCol = 0;
	}
	
	/**
	 * 默认样式
	 */
	public void setDefaultStyle() {
		sheet.setDefaultColumnWidth(20);//设置宽度为20个字节
		sheet.setDefaultRowHeightInPoints(18);//设置高度为18px
		style.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直    
	    style.setAlignment(HorizontalAlignment.CENTER);// 水平
	}
	
	
	/**
	 * 创建行
	 */
	public void createNewRow(){
		row = sheet.createRow(nextRow);
		previousRow = curRow;
		curRow = nextRow;
		nextRow++;
		curCol = nextCol = previousCol = 0;
	}
	
	/**
	 * 新增当前行单元格，默认样式
	 */
	public void createNewCol(){
		curCell = row.createCell(nextCol, CellType.STRING);
		previousCol = curCol;
		curCol = nextCol;
		nextCol++;
		curCell.setCellValue("");
		setDefaultCell();
	}
	
	/**
	 * 添加新单元格
	 * @param value 内容
	 */
	public void createNewCol(Object value){
		createNewCol();
		setObjectValue(value);
	}
	
	/**
	 * 具体化内容
	 * @param value
	 */
	public void setObjectValue(Object value){
		try {
			if(value instanceof Integer){
				int v = ((Integer) value).intValue();
				curCell.setCellValue(v);
			}else if(value instanceof String){
				curCell.setCellValue((String)value);
			}else if(value instanceof Double){
				double v =((Double) value).doubleValue();
				curCell.setCellValue(v);
			}else if(value instanceof Boolean){
				boolean v = ((Boolean)value).booleanValue();
				curCell.setCellValue(v);
			}else if(value instanceof Date){
				Date date = (Date)value;
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
				curCell.setCellValue(sdf.format(date));
			}else if (value instanceof Float) {
			    float v = ((Float) value).floatValue();
			    curCell.setCellValue(v);
			} else if (value instanceof Long) {
			    long v = ((Long) value).longValue();
			    curCell.setCellValue(v);
		    }
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("Excel单元格内容类型转换失败");
		}
		
	}
	
	/**
	 * 添加单独的日期类型
	 * @param value 值
	 * @param format 转换格式
	 */
	public void createNewCol(Date value, String format){
		createNewCol();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		curCell.setCellValue(sdf.format(value));
	}
	
	/**
	 * 放入Map数据自动生成
	 * @param datum
	 * @param dateFormat 时间转换格式
	 */
	public void putMapDatum(List<Map<String, Object>> datum, String dateFormat){
		for (int i=0; i<datum.size(); i++) {
			createNewRow();
			if(i==0){
				createNewCol("序号");
				setCellSize(7, 18);
				createNewRow();
			}
			createNewCol(i+1);
			for (String key : datum.get(i).keySet()) {
				if(i==0){
					row = sheet.getRow(previousRow);
					createNewCol(key);
					row = sheet.getRow(curRow);
					nextCol = curCol;
					curCol--;
					previousCol--;
				}
				Object o = datum.get(i).get(key);
				if(o instanceof Date){
					createNewCol((Date)o,dateFormat);
				}else createNewCol(o);
			}
		}
	}
	
	/**
	 * 设置单元格大小 高度设置即将改变整个行，宽度设置即将改变整个列
	 * @param cell
	 * @param width
	 * @param height
	 */
	public void setCellSize(HSSFCell cell, int width, float height){
		int col = cell.getColumnIndex();
		sheet.setColumnWidth(col, width * 256);
		HSSFRow row = sheet.getRow(cell.getRowIndex());
		row.setHeightInPoints(height);
	}
	
	/**
	 * 设当前单元格大小 高度设置即将改变整个行，宽度设置即将改变整个列
	 * @param cell
	 * @param width
	 * @param height
	 */
	public void setCellSize(int width, float height){
		int col = curCell.getColumnIndex();
		sheet.setColumnWidth(col, width * 256);
		HSSFRow row = sheet.getRow(curCell.getRowIndex());
		row.setHeightInPoints(height);
	}
	
	/**
	 * 设置单元格默认样式
	 */
	public void setDefaultCell(){
		setDefaultStyle();
		curCell.setCellStyle(style);
		setCellAroundBorder();
	}
	/**
	 * 设置单元格周围有边框
	 * @param cell
	 */
	public void setCellAroundBorder(){
		CellStyle cs = curCell.getCellStyle();
		cs.setBorderTop(BorderStyle.THIN);
		cs.setBorderBottom(BorderStyle.THIN);
		cs.setBorderLeft(BorderStyle.THIN);
		cs.setBorderRight(BorderStyle.THIN);
	}
	
	public HSSFCell getCurCell(){
		return curCell;
	}
	
	
	/**
	 * 输出excel文件至服务器中
	 * @param file
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void export(File file) throws FileNotFoundException, IOException{
		wb.write(new FileOutputStream(file));
	}
	
	/**
	 *  输出excel文件至服务器中
	 * @param fileName 文件名
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public boolean export(String fileName) throws FileNotFoundException, IOException{
		if(fileName == null) return false;
		if(!fileName.endsWith(".xls")) return false;
		String url = getDefaultPath() + fileName;
		wb.write(new FileOutputStream(new File(url)));
		return true;
	}
    
	/**
	 * 获得临时文件存储位置，classPath必须在WEB-INF/classes/下
	 * @return
	 */
	public String getDefaultPath(){
		String url = this.getClass().getResource("/").getFile();
		if(url.endsWith("WEB-INF/classes/")){
			url = url.substring(0,url.indexOf("WEB-INF/classes/")) + "download/temp/";
		}
		return url;
	}
	
	public String getFileName(){
		return System.currentTimeMillis()+".xls";
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
